package com.cares.event.utils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.cares.event.constant.EventFlowConstant;
import com.cares.event.constant.XmlNodeConstant;
import com.cares.event.dto.Task;

public class EventFlowXmlUtils {
	
	/**
	 * param： jsflowProcess--流程实体
	 * 根据流程,获取开始节点后的第一个任务
	 */
	public static Element getStartTask(String xml){
		
		Element rootElement = DomUtils.getRootbyStrXml(xml);
		//开始节点名称
		Element StartNode = DomUtils.getStartNodeByName(rootElement);
		//获取开始节点的transition 子节点
		Element start_transition = (Element) StartNode.elementIterator(XmlNodeConstant.NODE_TRANSITION).next();
		//获取transition节点的to属性
		String to_name = start_transition.attributeValue(XmlNodeConstant.NODE_TRANSITION_ATTR_TO);
		
		//获取第一个任务 
		return DomUtils.getNodeByName(rootElement, XmlNodeConstant.NODE_TASK_AUTO, XmlNodeConstant.NODE_ATTR_NAME, to_name);
	}

	/**
	 * @param xml 流程xml格式文件
	 * @param task_attr_name  任务name属性对应的值
	 * @return
	 */
	public static boolean isFirstTask(String xml, String task_attr_name_value){
		return task_attr_name_value.equals(getStartTask(xml).attributeValue(XmlNodeConstant.NODE_ATTR_NAME));
		
	}
	
	/**
	 * 
	 * @param xml 流程xml格式文件
	 * @param attrNameValue 目标任务的name属性值
	 * @return
	 */
	public static Element getTaskByAttrName(String xml, String attrNameValue){
		Element rootElement = DomUtils.getRootbyStrXml(xml);
		Element nextElement = DomUtils.getNodeByAttrName(rootElement, attrNameValue);
		return nextElement;
	}
	
	/**
	 * param： jsflowProcess--流程实体, attrNameValue: 下一个节点的name属性值
	 * 获取获取下一个任务节点------可能是多个任务，有待后续变更*************
	 */
	public static List<Element> getNextTask(String xml, String attrNameValue, Task task){
		
		List<Element> results = new ArrayList<Element>();
		Element rootElement = DomUtils.getRootbyStrXml(xml);
		
		//下个节点
		Element nextElement = DomUtils.getNodeByAttrName(rootElement, attrNameValue);
		String nextNodeName = nextElement.getName();
		//如果下个节点是分叉或者汇聚则，根据task的输出值判断，继续查找下一个任务节点
		if(XmlNodeConstant.NODE_FORK.equals(nextNodeName) || XmlNodeConstant.NODE_JOIN.equals(nextNodeName)){ //分叉,汇聚
			Iterator iter = nextElement.elementIterator(XmlNodeConstant.NODE_TRANSITION);
			Element temp = null;
			//表达式判断后的流转方向，即下个节点名称并获取节点任务
			while(iter.hasNext()){
				temp = (Element)iter.next();
				results.add(DomUtils.getNodeByAttrName(
								rootElement,temp.attributeValue(XmlNodeConstant.NODE_TRANSITION_ATTR_TO)));
			}
		}else{
			results.add(nextElement);
		}
		return results;
	}
	
	/**
	 * 添加或修改节点属性状态
	 * @param xml
	 * @param task
	 * @param state
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static String changeNodeAttribute(String xml, Task task, String state){
		Document doc = null;
		 try {
			 doc = DocumentHelper.parseText(xml); // 将字符串转为XML，并获取根对象
		 }catch (DocumentException e) {
			 e.printStackTrace();
		 } catch (Exception e) {
			 e.printStackTrace();
		 }
		 Element root = doc.getRootElement(); 
		 Element taskElement = DomUtils.getNodeByAttrName(root, task.getTaskNameValue());
		 if(null == taskElement.attribute(XmlNodeConstant.NODE_ATTR_STATE)){
			 taskElement.addAttribute(XmlNodeConstant.NODE_ATTR_STATE, state);
		 }else{
			 taskElement.setAttributeValue(XmlNodeConstant.NODE_ATTR_STATE, state);
		 }
		return doc.toString();
	}
	
	/*
	 * 判断汇聚任务前面的并发任务是否全部成功执行完成
	 * collectTaskName: 汇聚任务name属性名称
	 */
	public static boolean isConcurrentTaskFinish(String xml, String collectTaskName){
		Element rootElement = DomUtils.getRootbyStrXml(xml);
		Iterator iterator =rootElement.elementIterator(XmlNodeConstant.NODE_FORK);
		//1、获取前面fork的name属性值
		String lastForkName = "";
		while(iterator.hasNext()){
			Element forkTemp = (Element)iterator.next();
			if(DomUtils.isIncludeAttr(forkTemp, XmlNodeConstant.NODE_TRANSITION, XmlNodeConstant.NODE_TRANSITION_ATTR_TO, collectTaskName)){
				lastForkName = forkTemp.attributeValue(XmlNodeConstant.NODE_ATTR_NAME);
			}
		}
		//2、查找指向这个fork的Element，判读任务状态是否全部完成
		Iterator taskItera =rootElement.elementIterator(XmlNodeConstant.NODE_TASK_AUTO);
		boolean result = true;
		while(taskItera.hasNext()){
			Element taskTemp = (Element)taskItera.next();
			if(DomUtils.isIncludeAttr(taskTemp, XmlNodeConstant.NODE_TRANSITION, XmlNodeConstant.NODE_TRANSITION_ATTR_TO, lastForkName)){
				if(!EventFlowConstant.EVENT_TASK_STATE_FINISH.equals(
						taskTemp.attributeValue(XmlNodeConstant.NODE_ATTR_STATE))){
					result = false;
				}
			}
		}
		return result;
	}
	
	
	/**
	 * 解析事件任务节点
	 */
	public static Task readElement(Element element){
		
		Task task = new Task();
		//任务name属性值
		task.setTaskNameValue(element.attributeValue(XmlNodeConstant.NODE_ATTR_NAME));
		//任务类型
		task.setTaskType(element.attributeValue(XmlNodeConstant.NODE_TASK_AUTO_TYPE));
		//接收的参数值
		task.setInValue(element.attributeValue(XmlNodeConstant.NODE_TASK_AUTO_INVALUE));
		//输出的参数
		task.setInValue(element.attributeValue(XmlNodeConstant.NODE_TASK_AUTO_OUTVALUE));
		// 自动任务节点-延时执行的时间
		task.setInValue(element.attributeValue(XmlNodeConstant.NODE_TASK_AUTO_LAYTIME));
		//自动任务节点-任务参数1
		task.setInValue(element.attributeValue(XmlNodeConstant.NODE_TASK_AUTO_TASKPARAM1));
		//自动任务节点-任务参数2
		task.setInValue(element.attributeValue(XmlNodeConstant.NODE_TASK_AUTO_TASKPARAM2));
		//自动任务节点-任务参数3
		task.setInValue(element.attributeValue(XmlNodeConstant.NODE_TASK_AUTO_TASKPARAM3));
		return task;
	}
}
